package com.kede.app.service.impl;

import com.kede.app.domain.TransferLog;
import com.kede.app.domain.Users;
import com.kede.app.repository.UsersRepository;
import com.kede.app.service.mapstruct.UsersMapper;
import com.kede.exception.EntityExistException;
import com.kede.utils.ValidationUtil;
import com.kede.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.kede.app.repository.TransferLogRepository;
import com.kede.app.service.TransferLogService;
import com.kede.app.service.dto.TransferLogDto;
import com.kede.app.service.dto.TransferLogQueryCriteria;
import com.kede.app.service.mapstruct.TransferLogMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.kede.utils.PageUtil;
import com.kede.utils.QueryHelp;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @description 服务实现
* @author Pr.li
* @date 2023-05-11
**/
@Service
@RequiredArgsConstructor
public class TransferLogServiceImpl implements TransferLogService {

    private final TransferLogRepository transferLogRepository;
    private final TransferLogMapper transferLogMapper;

    private final UsersRepository usersRepository;

    @Override
    public Map<String,Object> queryAll(TransferLogQueryCriteria criteria, Pageable pageable){
        Page<TransferLog> page = transferLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        page.get().forEach(transferLog -> {
            Optional<Users> byId = usersRepository.findById(transferLog.getUserid());
            if (byId.isPresent()) {
                transferLog.setUsername(byId.get().getUsersName());
                transferLog.setUserphone(byId.get().getUsersPhone());
            }
        });
        return PageUtil.toPage(page.map(transferLogMapper::toDto));
    }

    @Override
    public List<TransferLogDto> queryAll(TransferLogQueryCriteria criteria){
        return transferLogMapper.toDto(transferLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public TransferLogDto findById(Integer id) {
        TransferLog transferLog = transferLogRepository.findById(id).orElseGet(TransferLog::new);
        ValidationUtil.isNull(transferLog.getId(),"TransferLog","id",id);
        return transferLogMapper.toDto(transferLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TransferLogDto create(TransferLog resources) {
        if(transferLogRepository.findByOutDetailNo(resources.getOutDetailNo()) != null){
            throw new EntityExistException(TransferLog.class,"out_detail_no",resources.getOutDetailNo());
        }
        return transferLogMapper.toDto(transferLogRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TransferLog resources) {
        TransferLog transferLog = transferLogRepository.findById(resources.getId()).orElseGet(TransferLog::new);
        ValidationUtil.isNull( transferLog.getId(),"TransferLog","id",resources.getId());
        TransferLog transferLog1 = transferLogRepository.findByOutDetailNo(resources.getOutDetailNo());
        if(transferLog1 != null && !transferLog1.getId().equals(transferLog.getId())){
            throw new EntityExistException(TransferLog.class,"out_detail_no",resources.getOutDetailNo());
        }
        transferLog.copy(resources);
        transferLogRepository.save(transferLog);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            transferLogRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<TransferLogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TransferLogDto transferLog : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("用户id", transferLog.getUserid());
            map.put("关联批次id 商家批次单号", transferLog.getOutBatchNo());
            map.put("商家明细单号", transferLog.getOutDetailNo());
            map.put(" 转账金额", transferLog.getTransferAmount());
            map.put("转账备注", transferLog.getTransferRemark());
            map.put("openid", transferLog.getOpenid());
            map.put("明细状态", transferLog.getDetailStatus());
            map.put("明细失败原因", transferLog.getFailReason());
            map.put("创建时间", transferLog.getCreatetime());
            map.put("更新时间", transferLog.getUpdatetime());
            map.put("应用发起来源 ", transferLog.getType());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}